package controllers;

import play.*;

import play.mvc.*;

import java.util.*;

import models.*;

/**
 * Tags Controller that links the views of the tag and the model class Tag
 * 
 * @author Nesreen elgohary
 * 
 */

public class Tags extends Controller {
	public static Long ideaIdd;

	/**
	 * displays an HTML page that takes the input parameters for editing a tag
	 * 
	 * @param tagId
	 *            id of the tag that will be edited
	 * @author Nesreen elgohary
	 */
	public static void editTag(Long tagId) {
		// Tag tag = Tag.findById(id);
		render(tagId);
	}

	/**
	 * takes the id of the tag that will be modified and gets the tag, then it
	 * takes the new name of the tag and then call the method editTag which will
	 * change the old name of the tag with the new one
	 * 
	 * @param tagId
	 *            the id of the tag that will be modified
	 * @author Nesreen elgohary
	 */
	public static void tagNewName(Long tagId) {
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Tag tag = Tag.findById(tagId);
		Organization organization = tag.organization;
		String newName = params.get("tag.name");
		String details = ", " + tag.name + "  tag that is in organization "
				+ organization.name + " has been renamed to " + newName;
		user.sendNotificationWithType(details, tag.subscribers, "Tag", tag.id);
		tag.editTag(newName);
		tag.save();
		showTag(tag.id);
	}

	/**
	 * displays an HTML page with a message confirming the tag modification
	 * 
	 * @param tagId
	 *            id of the edited tag
	 * @author Nesreen elgohary
	 */
	public static void showTagName(Long tagId) {
		Tag tag = Tag.findById(tagId);
		render(tag);
	}

	/**
	 * takes the organization id, and from the organization calls method
	 * unusedTags that returns a list of the unused tags and renders it
	 * 
	 * @param organizationId
	 *            the organization id
	 * @author Nesreen elgohary
	 */
	public static void listOfUnusedTags(Long organizationId) {
		Organization organization = Organization.findById(organizationId);
		List<Tag> allTags = organization.unusedTags();

		render(allTags);
	}

	/**
	 * takes a tag id then gets the tag then show its name
	 * 
	 * @param tagId
	 *            id of the tag that will be shown
	 * @author Nesreen elgohary
	 * 
	 */

	public static void showTag(Long tagId) {

		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);

		Tag tag = Tag.findById(tagId);
		boolean inSubscriber = tag.userinSubscribers(user);
		tag.save();

		render(tag, inSubscriber);
	}

	/**
	 * connects to an a HTML page that allows a tag to be deleted
	 * 
	 * @author Nesreen elgohary
	 */
	public static void deleteTag() {
		render();
	}

	/**
	 * takes tag id as an input then gets the tag and check if the tag can be
	 * deleted, and if it returns true then it will delete and connects with an
	 * html page that has a confirmation for the deletion and notifies the tag
	 * subscribers
	 * 
	 * @param tagId
	 *            id of the tag that will be deleted
	 * @author Nesreen elgohary
	 */
	public static void tagDeleted(Long tagId) {
		try{
		String userIdString = session.get("userId");
		if (userIdString == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(userIdString);
		User user = User.findById(userId);
		Tag tag = Tag.findById(tagId);
		Organization organization = tag.organization;
		String details = ", the tag that is named " + tag.name
				+ " in organization " + organization.name
				+ " has been deleted! ";
		if (tag.deleteTag() == true) {
			user.sendNotificationWithType(details, tag.subscribers, "Tag",
					tag.id);
			tag.delete();
			showDeleteMsg();
		}}catch (NullPointerException error) {
			Requests.contentNotFound();
		}

	}

	/**
	 * displays a page will the deletion message in case a tag was successfully
	 * deleted
	 * 
	 * @author Nesreen elgohary
	 */
	public static void showDeleteMsg() {
		render();
	}

	/**
	 * directs to the page where tag values are inserted
	 * 
	 * @param organizationId
	 *            Organization id that the tag will be added to
	 * @author Ghada Abu Shady
	 */
	public static void insertTag(Long organizationId) {
		Organization organization = Organization.findById(organizationId);
		render(organization);
	}

	/**
	 * creates a tag and checks whether the
	 * created tag is a duplicate or not. it adds the creator to the list of the
	 * tag subscribers
	 * 
	 * @param organizationID
	 *            Organization id the tag will be created into
	 * 
	 * @author Ghada Abu Shady
	 */
	public static void createTag(Long organizationId) {
		Organization organization = Organization.findById(organizationId);
		String id = session.get("userId");
		if (id == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(id);
		User user = User.findById(userId);
		String tagName = params.get("TagName");
		List<Tag> tagList = organization.tags;
		boolean f = false;
		for (int counter = 0; counter < tagList.size(); counter++) {
			if (tagList.get(counter).name.equals(tagName) || tagName.isEmpty()
					|| tagName.matches("[a-zA-z0-9]*") == false) {
				f = true;
				handleDuplicateTags(organizationId);
			}
		}

		Tag tag = new Tag(tagName, organization).save();
		organization.tags.add(tag);
		organization.save();
		tag.subscribers.add(user);
		tag.save();

		render(tag);

	}

	/**
	 * directs to the page that displays that the tag name inserted is a
	 * duplicate
	 * 
	 * @param organizationID
	 *            organization id that Duplicate tags will be handled in
	 * @author Ghada Abu Shady
	 */
	public static void handleDuplicateTags(Long organizationID) {
		Organization organization = Organization.findById(organizationID);
		render(organization);
	}

	/**
	 * directs to the page where tag ideas are displayed
	 * 
	 * @param tagId
	 *            the id of tag that its ideas will be shown
	 * 
	 * @author Ghada Abu Shady
	 */

	public static void showTagIdeas(Long tagId) {
		Tag tag = Tag.findById(tagId);
		Set<Idea> ideas = tag.Ideas;
		render(ideas, tag);
	}

	/**
	 * directs to the page where tag topics are displayed
	 * 
	 * @param tagId
	 *            the id of tag that it's topics will be shown
	 * 
	 * @author Ghada Abu Shady
	 */

	public static void showTagTopics(Long tagId) {
		Tag tag = Tag.findById(tagId);
		Set<Topic> topics = tag.Topics;
		render(topics, tag);
	}

	/**
	 * directs to the page that shows list of organizations
	 * 
	 * @author Ghada Abu Shady
	 */

	public static void showOrgTags() {
		List<Organization> organizationsList = Organization.getOrganizations();
		render(organizationsList);
	}

	/**
	 * directs to the page where list of tags that belong to a certain
	 * organization are displayed
	 * 
	 * @param organizationId
	 *            the id of organization its tags will be displayed
	 * 
	 * @author Ghada Abu Shady
	 */
	public static void orgTags(Long organizationId) {

		Organization organization = Organization.findById(organizationId);
		organization.save();
		List<Tag> tagList = organization.tags;
		String id = session.get("userId");
		if (id == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(id);
		User user = User.findById(userId);
		boolean userIsLead = false;
		if (user.id == organization.lead.id) {
			userIsLead = true;
		}
		render(tagList, userIsLead, organization);
	}

	/**
	 * displays tags that the user will select one of them to tag his ideas
	 * or topics
	 * 
	 * @param ideaId
	 *            the id of idea to be tagged
	 * @param topicId
	 *            the id of topic to be tagged
	 * 
	 * @author Ghada Abu Shady
	 */
	public static void showOrgTagsForTagging(Long ideaId, Long topicId) {

		if (ideaId != 0l) {
			Organization organization;
			Idea idea = Idea.findById(ideaId);
			List<Tag> tagList = new ArrayList();
			if (idea.topic != null) {
				tagList = idea.topic.entity.organization.tags;
				organization = idea.topic.entity.organization;
			} else {
				if (idea.entity != null) {
					tagList = idea.entity.organization.tags;
					organization = idea.entity.organization;
				} else {
					tagList = idea.organization.tags;
					organization = idea.organization;
				}
			}
			String idString = session.get("userId");
			Long userid = Long.parseLong(idString);
			User user = User.findById(userid);
			boolean userIsLead = false;
			if (user.id == organization.lead.id) {
				userIsLead = true;
			}
			render(tagList, userIsLead, organization, idea);
		}

		if (topicId != 0l) {
			Topic topic = Topic.findById(topicId);
			Organization organization = topic.entity.organization;
			String idString = session.get("userId");
			Long userid = Long.parseLong(idString);
			User user = User.findById(userid);
			boolean userIsLead = false;
			if (user.id == organization.lead.id) {
				userIsLead = true;
			}
			List<Tag> tagList = new ArrayList();
			tagList = topic.entity.organization.tags;
			render(tagList, organization, userIsLead, topic);
		}

	}

	/**
	 * displays tags that the user will select one of them to untag his ideas
	 * or topics
	 * 
	 * @param ideaId
	 *            the id of idea to be untagged
	 * 
	 * @param topicId
	 *            the id of topic to be untagged
	 * @author Ghada Abu Shady
	 */
	public static void showOrgTagsForUnTagging(Long ideaId, Long topicId) {

		if (ideaId != 0l) {
			Organization organization;
			Idea idea = Idea.findById(ideaId);
			List<Tag> tagList = new ArrayList();
			if (idea.topic != null) {
				tagList = idea.topic.entity.organization.tags;
				organization = idea.topic.entity.organization;
			} else {
				if (idea.entity != null) {
					tagList = idea.entity.organization.tags;
					organization = idea.entity.organization;
				} else {
					tagList = idea.organization.tags;
					organization = idea.organization;
				}
			}
			String idString = session.get("userId");
			Long userId = Long.parseLong(idString);
			User user = User.findById(userId);
			boolean userIsLead = false;
			if (user.id == organization.lead.id) {
				userIsLead = true;
			}
			render(tagList, userIsLead, organization, idea);
		}
		if (topicId != 0l) {
			Topic topic = Topic.findById(topicId);
			Organization organization = topic.entity.organization;
			String idString = session.get("userId");
			Long userid = Long.parseLong(idString);
			User user = User.findById(userid);
			boolean userIsLead = false;
			if (user.id == organization.lead.id) {
				userIsLead = true;
			}
			List<Tag> tagList = new ArrayList();
			tagList = topic.entity.organization.tags;
			render(tagList, organization, userIsLead, topic);
		}

	}

	/**
	 * displays a message that tagging is successful and it performs the
	 * action of tagging here
	 * 
	 * @param object
	 *            String of what needs to be tagged whether idea or topic
	 * 
	 * @param tagId
	 *            the id of tag
	 * 
	 * @author Ghada Abu Shady
	 */

	public static void tagSuccess(String object, Long tagId) {
		String idRetrieve = "";
		if (object.charAt(0) == 't') {
			for (int counter = 1; counter < object.length(); counter++) {
				idRetrieve += object.charAt(counter);
			}
			Long topicId = Long.parseLong(idRetrieve);
			Topic topic = Topic.findById(topicId);
			Tag tag = Tag.findById(tagId);
			topic.tags.add(tag);
			topic.save();
			tag.Topics.add(topic);
			tag.save();

			render(topic);
		}

		else {
			if (object.charAt(0) == 'i') {
				for (int counter = 1; counter < object.length(); counter++) {
					idRetrieve += object.charAt(counter);
				}
				Long ideaId = Long.parseLong(idRetrieve);
				Idea idea = Idea.findById(ideaId);
				Tag tag = Tag.findById(tagId);
				idea.tags.add(tag);
				idea.save();
				tag.Ideas.add(idea);
				tag.save();
				render(idea);
			}
		}

	}

	/**
	 * displays a message that untagging is successful and it performs the
	 * action of untagging here
	 * 
	 * @param object
	 *            String of what needs to be untagged whether idea or topic
	 * 
	 * @param tagId
	 *            the id of tag
	 * 
	 * @author Ghada Abu Shady
	 */
	public static void unTagSuccess(String object, Long tagId) {
		String idRetrieve = "";
		if (object.charAt(0) == 't') {
			for (int counter = 1; counter < object.length(); counter++) {
				idRetrieve += object.charAt(counter);
			}
			Long topicId = Long.parseLong(idRetrieve);
			Topic topic = Topic.findById(topicId);
			Tag tag = Tag.findById(tagId);
			topic.tags.remove(tag);
			topic.save();
			tag.Topics.remove(topic);
			tag.save();

			render(topic);
		}

		else {
			if (object.charAt(0) == 'i') {
				for (int counter = 1; counter < object.length(); counter++) {
					idRetrieve += object.charAt(counter);
				}
				Long ideaId = Long.parseLong(idRetrieve);
				Idea idea = Idea.findById(ideaId);
				Tag tag = Tag.findById(tagId);
				idea.tags.remove(tag);
				idea.save();
				tag.Ideas.remove(idea);
				tag.save();
				render(idea);
			}
		}
	}

	/**
	 * displays tags that the user is subscribed to
	 * 
	 * @author Ghada Abu Shady
	 */

	public static void showUserTags() {
		String id = session.get("userId");
		if (id == null) {
			Home.home(null, null, "Please Login");
		}
		Long userId = Long.parseLong(id);
		User user = User.findById(userId);
		List<Tag> tagList = Tag.findAll();
		List<Tag> tagsResult = new ArrayList();
		for (int counter = 0; counter < tagList.size(); counter++) {
			for (int secondCounter = 0; secondCounter < tagList.get(counter).subscribers
					.size(); secondCounter++) {
				if (tagList.get(counter).subscribers.get(secondCounter).id == user.id) {
					tagsResult.add(tagList.get(counter));
					break;
				}
			}
		}

		render(tagsResult);
	}

	/**
	 * adds a user to subscriber list
	 * 
	 * @author Sara Assem
	 * @param Long
	 *            id id of the tag
	 */
	public static void addSubscriber(Long tagid) {
		Tag tag = Tag.findById(tagid);
		String idstring = session.get("userId");
		Long userid = Long.parseLong(idstring);
		User user = User.findById(userid);
		user.tags.add(tag);
		tag.addUserToSubscribers(user);
		tag.save();
		user.save();
		showTag(tagid);

	}

	/**
	 * removes user from subscriber list
	 * 
	 * @author Sara Assem
	 * @param Long
	 *            id id of the tag
	 */

	public static void removeSubscriber(Long tagid) {
		Tag tag = Tag.findById(tagid);
		String idstring = session.get("userId");
		Long userid = Long.parseLong(idstring);
		User user = User.findById(userid);
		user.tags.add(tag);
		tag.removeUserFromSubscribers(user);
		tag.save();
		user.save();
		showTag(tagid);

	}

	/**
	 * renders the tags Homepage it renders the user and the
	 * boolean userIsLead to check whether the organization allows the idea
	 * developer to create a tag or not
	 * 
	 * @param organizationID
	 *            to get the tags of specific organization
	 * 
	 * @author Ghada Abu Shady
	 * @author Mohamed Abdel Kader
	 */
	public static void tagHome(Long organizationID) {

		Organization organization = Organization.findById(organizationID);
		String idstring = session.get("userId");
		Long userId = Long.parseLong(idstring);
		User user = User.findById(userId);
		boolean userIsLead = false;
		boolean userIsAdmin = false;
		if (user == organization.lead) {
			userIsLead = true;
		}
		if(user.email.equals("admin@admin.com")){
			userIsAdmin=true;
		}
		render(organization, user, userIsLead, userIsAdmin);

	}
}
